home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
basic
/
glib19.zip
/
MACRO19.DOC
< prev
next >
Wrap
Text File
|
1991-06-27
|
71KB
|
2,114 lines
GLIB Macro-Routines
Copyright (C), InfoSoft 1987-1990, 1991
GLIB contains and premieres several more complex routines not
available in ANY other library collection whatever the price. These
routines do more, much more, than the average call to simply save the
screen image or whatever. These are more like complete programs in
themselves, yet they remain callable from QB (and in some cases 'C')
to perform a function, or set of functions. For lack of a better
term, we are calling this type of callable routine a macro-routine
to differentiate them from simple calls or primitives available from
most other run of the mill library collections.
In spite of the fact that these tend to be far more complex and
functional than a typical sub program primitive, they tend to remain
mainly assembler; they may have the look or profile of a higher-level
BASIC routine, but most remain in high-speed assembler. Only MFed
and FlexMenu are in BASIC.
GLib Macro Routines
A. MFed - A complete input handler for editing input or
that supports MACROS
B. Clock - An installable and accurate time display.
C. QCalc - A complete, full featured calculator.
D. FlexMenu - All purpose, flexible menuing routine
E. StatLine - A set of status line control routines.
F. DialogBox - A lightning fast way to perform short I/O
functions with an end user.
Copyright (C) InfoSoft 1986-1989, 1990
A. Macro Input Editor
Copyright (C) InfoSoft, 1987 - 1990, 1991
I. Introduction
There are several, indeed many, text input handlers around now
you have now stumbled upon the most functional of them all. MFed is
fully modular, requires no event trapping switch and is packed with
features. MFed was designed to be a powerful all-purpose input
control editor suitable for virtually any and all keyboard input
situation, yet still remain modular, self contained and requires a
minimum of overhead. In short, it provides for maximum functionality
with a minimum of set up, dependencies and overhead.
MFed, which stands for Macro Field Editor, is modular: it can
be called from the main code of most any another program very
easily.
MFed is highly configuarable: You can change most any of the
operating parameters with the change of a flag or two.
MFed does not require the use of any event trapping switch, it
identifies extended key codes on its own, like most any text
input routine should.
Finally, MFed utilizes the awesome power of macros. This allows
the end user to save loads of keystrokes even redefining them on
the fly if you choose! Even if you do not use macros in your
application, MFed remains a highly useful and powerful text input
control module.
Copyright (C) InfoSoft 1986-1989, 1990
II. MFed Parameters, Syntax
MFED uses several switches and 2 arguments to control the
flow and text input. The formal or direct parameters are:
Text$ - The text string to edit.
FSize - An integer telling MFED the maximum length allowed for
the TEXT$, the current text to be edited.
Macro$() - An array of strings for use as macro assignments to
the ALT + Alpha keys
You should understand that you can actually use any names that
suit you in invoking MFED. That is, you could use ED$ instead of
TEXT$, or T$, or whatever you want. MFED will operate just as ex-
pected, as long as you pass them in the right order. The correct
syntax is:
MRetCode = MFed(text$, fsize%, Macro$())
The importance of FSize is that MFed will not allow input after
that maximum size is reached, and maybe beep (bleep actually). MFed
does not change FSize on the return, so be sure to reset it for each
successive call.
III. Incorporating MFED to your code
MFed works off of 3 formal arguments (covered above) and
several COMMON parameters shared with the main, calling program. This
allows you to share some parameters with MFed very easily such as
Foreground Color, upper casing etc.
The actual use and meaning of these common parameters are
covered later, here we are explaining how to set up for MFed to work
in your program. This is done by simply including the following line
in the beginning of your main code:
COMMON /MFedVars/ fg%, bg%, fgd%, bgd%, Alarm%, bad$, editted%,_
hatch%, Mac%, nums%, num$, upcase%, RngLo#, RngHi#
It is important that you list them EXACTLY as shown, ie in the
order shown, WITH the type declarations. The first four are fore-
ground and background colors and the rest are listed alphabetically.
Copyright (C) InfoSoft 1986-1989, 1990
Note that such COMMON statements must appear in your code
BEFORE any executable statements. If you are not familiar with the
use of COMMON it is suggested that you review this in the QB man-
ual(s). Also refer to the MFedDemo source for proper set up. In
implementing the MFed variables, we have opted to make several of them
COMMON to allow MFed to read and literally share these variables with
your main program and at the same time, keeps you from having to pass
all of them as formal arguments to MFed. That is, intead of:
MCode = MFed (t$, fsiz, Macro$(), fg, bg, fgd, bgd, alarm,_
editted, nums, num$, upcase, URng#, LRng#)
all we do is:
MCode = MFed(t$, fsiz, Macro$())
Additionally, a benefit of this is that the COMMON switches are
typically used or reset MUCH less often in use than say, the text$
would be; for example, most likely you would set the color switches
once (fg, fgd, bg and bgd), but text$ gets changed at almost every
call.
The use of a blockname (/MFedVars/) prevents MFED from interfering
with other COMMON or COMMON SHARED variables, more precisely, it
allows the USE of additional COMMON or COMMMON SHARED variables. To
name additional variables as COMMON declare them like this:
DEFINT a-z
COMMON SHARED /MFedVars/ fg%, bg%, fgd%, bgd%, Alarm%, bad$,_
editted%, hatch%, Mac%, nums%, num$, upcase%,_
RngLo#, RngHi#
COMMON SHARED /newblock/ arg1, arg2, arg3 ' different block
COMMON SHARED a,_ ' "blank" block of
b,_ ' COMMON variables
c,_
z
Note that /MFedvars/ need not carry the SHARED attribute, but the
use of a blockname allows MFED to share those variables that it needs
and ONLY those, ie a SIZE error is not encountered if you use other
COMMON variables. This allows for maximum flexibility.
Of the /MFedvars/ variables, only EDITTED, a more or less aux-
iliary flag is ever altered by MFed.
Copyright (C) InfoSoft 1986-1989, 1990
IV. Internal Editing Keys
Internally, MFed does several things to provide a set of
powerful, professional editting functions to it's operation. First,
lets look at the editting functions and keys recognized:
[Home] Places cursor at start of text or field.
[End] Places cursor at first blank at end of the text.
[Ctrl-End] Clear line from cursor to end of line.
[Ctrl-X] Clear all text from current field.
[Ctrl-U] Undoes current edit. This does not restore the text to
it's form in a disk text file, but restores the text to
the form it was UPON ENTRY TO MFED. It cannot know
what the text was or what form it was in PRIOR to the
CALL.
Arrow Keys Move one character Right or Left. MFED will not allow
the user to Cursor right into the hatched area if that
means that more than 1 space trails the text. That is,
via the the right arrow, it will not allow more than 2
consecutive spaces, as in "J. DOE " or "J Q Public".
Multiple spaces can be achieved via the insert key
or space however.
Ctrl-Arrow Moves one word right or left
Keys
[Tab] Moves over 5 spaces without disturbing text.
[Back Tab] Back up 5 spaces without disturbing text.
[Ins] Insert works as expected, allowing text to be inserted
at the cursor, and changes the cursor to a block. The
Insert state is toggled off upon exiting MFed or
"finishing" the field or text.
[Del] As expected, deletes characters right of the cursor.
[Alt-A] Invokes macro tied to that key if your program is
to [Alt-Z] allowing Macros.
Copyright (C) InfoSoft 1986-1989, 1990
V. MFed Return Codes - FCODE
Another major feature of MFed is the returns code. This indicates
to you what key is pressed to exit the routine and therefore can
indicate other functions to be handled by your code.
MFed Returns:
Location error - -1
Enter - 0
Up Arrow - 1 Ctrl PgUp - 5
Dn Arrow - 2 PgDn - 6
PgUp - 3 (Return codes 7 and 8 not used)
PgDn - 4 Escape - 9
F1 - F10 returns 11 thru 20
Note that shifted function keys are not trapped or returned, and
returns 7 and 8 are omitted to allow function keys to return intuitive
values.
By acting on the return, MFED acts not only as a text input
control module but also as a virtual control center: your application
can respond to F1 with Help, F2 to search for a string, F3 to add a
record and so forth.
The return of a -1 code indicates that you have attempted to
execute the MFed editing functions too close to the edge of the
screen. For example, attempting to edit a field of 8 past postion 72
on the screen will return this. This simply precludes a runtime error
by exiting gracefully.
VI. Internal Handling, COMMON Parameters
MFed does a few things internally on its own and a few others you
control and change throughout the course of your program by resetting
the COMMON parameters. If you are not familiar with SHARED parameters
you should refer to your QB manual. These are not passed as formal
arguments inside the parentheses when the program is CALLed but are
set in your main program.
o The ALARM parameter indicates whether sound is to be on or off.
The sound is more of a bleep than a beep. If this switch is
set (non zero) it allows the bleep sound effect to sound at
various times:
Copyright (C) InfoSoft 1986-1989, 1990
- An attempt to cursor right when the string has reached
FSize (maximum length).
- An attempt to enter an invalid character (an alpha
character when nums is ON).
- When an inserted character will cause the text to exceed
the maximum length.
- Cursor left attempted left of first character position.
- If cursor right appends more than 1 successive blanks to
the text.
Regardless of the state of ALARM, MFed disregards any such
illegal activities. Alarm just adds an error sound to the process.
While the error sound has it's uses, thre are times when it is inap-
propriate, such as in an office bullpen setting where such BLEEPING
would be annoying - here, clear the Alarm flag (Alarm = 0).
o MFed also highlights the current text or data as well as
providing the hatching. When the editing is completed, and one
of the 15 FCODE keys are hit to exit the field (actually MFed
is exited, and control is returned to you), the highlighting is
turned off. This color control is handled thru the use of 2
sets of color codes: FG, BG and FGD and BGD. These must be
assigned valid BASIC color codes in the course of your main
code. At the start, MFed uses the FGD, BGD (as in
ForeGround_Data and BackGround_Data) colors and upon exiting,
redisplays it in the FG, BG colors. These only need to be set
once.
o BAD$ allows you to define invalid characters. One instance
where this is extremely handy is when the input will be written
to a sequential file and you want to preclude excess commas
from being written. Defining BAD$ as "," would cause MFed to
reject commas from being input and sound the alarm (depending
on the state of ALARM).
o EDITTED is treated as a flag to indicate that the text string
upon exiting MFed is different than it was at the start of the
CALL to MFed. This allows you to test to see if field in a
record has been altered. MFed only sets it to 1 never to 0.
Since MFed is just handling the input for different strings, it
never knows when a set of fields equalling a full record is
completed. EDITTED is how MFed tells you that something has
indeed been edited. ( Based on this flag, you can include code
in your application to flash a message that an EDIT is in
process, as is done in MFED-DEMO. It is also useful in
precluding certain functions if an edited record is not saved.
An example of this is shown in MFED-DEMO where paging is
disallowed if a record is edited and unsaved.)
Copyright (C) InfoSoft 1986-1989, 1990
o HATCH allows you to redefine the hatching character. Using the
value of FSize as the maximum length allowed, MFed provides
hatching from the end of the actual text to that maximum
length. If a string is longer than FSize upon entry to MFed,
it is truncated to the maximum length. The default character
for hatching is ASCII 176, but can be set to anything you wish
the HATCH variable.
o MAC allows you to enable or disable macro processing. If set
to 1, macros are enabled, and pressing Alt+ 'A' to 'Z' invokes
the macro you or your application has assined to that key. If
MAC is cleared or set to 0, macros are not allowed and ALT
keypresses are ignored.
o RngHi# and RngLo# allow for internal range checking of values.
If RngHi# does NOT equal RngLo#, then range checking will be in
effect. In this state, if an exit key is pressed (Enter, Up
Arrow etc) AND the value of the string being editted is LESS
than RngHi# AND GREATER than RngLo#, then MFed will consider
the string to be invalid and ONLY exit if the exit key was
[Esc] (this allows a way out of MFed even with 'invalid'
input). If Alarm is active, it will sound on such invalid
values.
o Input can be limited with the NUMS switch. Originally intended
to allow numbers only, it restricts input to the characters in
num$. For example, in a phone number entry the characters
"()-" may be allowable beyond 0-9, but in a dollar based entry
$ and "." may be allowable. So prior to invoking MFed, NUM$
would be set to "1234567890()-" for phone numbers, or
".1234567890$" for the dollar based entry. If NUMS is set (1)
and NUM$ is clear ( "" ) the default is "-123456789".
Obviously, this allows other limited inputs such as in gender
selections of M or F. Here, set UPCASE to 1, NUMS to 1 and
NUM$ to "MF".
o Caps or uppercase input from the keyboard can be forced on the
fly (ie without a separate call) via the UPCASE switch. Set
UPCASE to 1 or non zero for caps, 0 for to allow either lower
or upper case. When UpCase is set, it converts the input to
Upper.
Copyright (C) InfoSoft 1986-1989, 1990
VII. Macro Processing
MFed acts upon Alt-alpha keystrokes to insert the string
associated with that combination into the field being edited. The
power of this comes in applications that require repetitive stings to
be typed (such as city names). If your application requires that the
end user needs to type 'Shawnee Mission' or 'Overland Park' with any
sort of frequency, you could assign then as macros to the [Alt-S] and
[Alt-O] respectively. From there on, those strings could be entered
into the current field with a single shifted keystoke.
For your end user's added convenience, you can embed an exit key
to the end of a macro eliminating that step too! Specifically, you
could add CHR$(13) to either (or both/all) macros and after MFed fills
the field with the macro contents, it exists with FCode 0! Only
[Enter] (CHR$(13)) is handled this way and only when insert is OFF,
Macros are allowed (MAC = 1) and provided the macro size (LEN) is less
than or equal to FSiz.
MFED's macro processing automagically recognizes and respects the
INSERT state. That is, with INSERT OFF [Alt-S] overwrites whatever is
in the field with 'Shawnee Mission'; with INSERT ON, the string is
inserted at the current location as long as room permits.
Macros are stored in a conventional string array. These can be
hard coded in your application (eg Macro$(1) = "qwerty") or they can
be read from a disk file. Again, note that you can name the array
anything you wish so that a large application could alternately use
several macro arrays so that one could hold city names, another could
contain common account or reference numbers, another common zip codes
or area codes and so forth.
The Macro string array is a simple 35 element string array,
referenced as follows:
Elements 1 to 10 control the top alpha key macros: [Alt-Q] to [Alt-P]
Elements 15 to 23 control those tied to middle row: [Alt-A] to [Alt-L]
Elements 29 to 35 control the bottom row: [Alt-Z] to [Alt-M]
Note that not all 35 elements are used, eg a string stored to
Macro$(11) cannot be invoked.
A Macro array can be qucikly filled from a disk file as follows:
FOR x = 1 to 10
LINE INPUT #FilNo, Macro$(x)
NEXT x
FOR x = 15 to 23
LINE INPUT #FilNo, Macro$(x)
NEXT x
FOR x = 29 to 35
LINE INPUT #FilNo, Macro$(x)
NEXT x
CLOSE #FilNo
Copyright (C) InfoSoft 1986-1989, 1990
If you do not wish to use macro processing, there are two ways to
disallow it. The simplest is to only dimension Macro$() to 1. If the
macro array is less than 35, MFed assumes that you do not want to use
macros. Since the array is passed explicitly, it must be dimensioned
to at least 1 even if you are not using macros so that an error is not
encountered.
You can temporarily or selectively suspend macro processing by
setting MAC to 0. This causes MFed to ignore the macro processing
code regardless of any assignments to Macro$() and Alt-keypresses. If
the end user attempts to invoke a macro from a "blank" key, MFed emits
a short, quiet click so that touch and fast typists can be warned that
no macro was available.
Note that you can arrange your code to even edit macros on the
fly. By assigning this function to one of the function keys, all you
need do is edit a temporary string and then place it in the array:
CASE 13 ' assume F3 =edit macro
CALL SaveScrn(2001) ' Save the main MFed screen
CALL Windows(1, 1, 5, 25, 0, 0, 1, 78, "")
LOCATE 24, 20
PRINT "Press key of Macro to edit" ' find out which one
DO
m$ = inkey$
LOOP UNTIL m$ > ""
MacToEdit = ConvertKey(m$) ' write a function to check to
' see if it is a valid macro key
' return the scan code minus 15
ed$ = Macro$(MacToEdit)
Mac = 0 ' turn off macros for now
MCode = MFed(ed$, x, Macro$()) ' edit macro
IF MCode = 0 THEN ' update/save if Enter hit
Macro$(MacToEdit) = ed$ ' update macro array
END IF
Likewise, one of the function keys could be used to allow the
user to signal to your application to save the current macro list to
disk and yet another could be used to request a new set be loaded from
disk.
Copyright (C) InfoSoft 1986-1989, 1990
B. CLOCK
Copyright (C) InfoSoft 1986 - 1990, 1991
I. Introduction
CLOCK allows your program to provide an ongoing display of the
time time WITHOUT the hassle, heartache or overhead of executing GOSUB
statements to print TIME$.
CLOCK works much the same as a DOS level TSR, that is, it installs
itself in memory, latching onto to certain system interrupts to update
a display of the current time as needed. The format of the display is
" hh:mm:ss ?m " (12 hour format), with a trailing am or pm label.
The problem with most similar time display programs quite simply
is that they are not accurate! Over the long haul, a simple time
keeping process is most likely to lose about .02 seconds each second.
This may sound trivial or insignificant, but in a mere 5 minutes, the
time display can be off as much as 2 or 3 seconds!! If your program
is to run for hours on end, after a few hours, the time display will
simply be inaccurate to a wholly unacceptable degree.
To rectify this, CLOCK uses a secondary internal clock to es-
timate the amount of time lost from 'True' system time and periodical-
ly jumps ahead a second to adjust. The CLOCK in GLIB does not loose
an entire second until over 8 hours have passed! During that time,
CLOCK's time display consistently remained within a constant .5 to 1
second of the actual system time returned by TIME$. In fact, after 12
hours, CLOCK is incredibly still within 1 second! Over extremely long
periods, even CLOCK will eventually vary from true time, so for
applications that run continually, to adjust the time simply uninstall
and immediately re install CLOCK. This will allow it to re-synch with
the system time for another 8 to 10 hours.
Accuracy is only part of the superiority of CLOCK. The friendly
12 hour-based display with the am/pm label provides a positive, easy
to read display and the time display is fully configurable: it can be
located or 'popped up' any where on the screen and in any color
attribute. CLOCK will also emit a small, pleasant audible tone on the
hour and on the half hour (even this is configurable).
Since CLOCK does take of advantage of TSR-like programming
techniques, it is installed rather than simply called, to invoke it.
Likewise it MUST be uninstalled prior to your program termination. It
is advised that you fully develop and write your program without CLOCK
installed and only when it is fully debugged should you add CLOCK to
your code.
Copyright (C) InfoSoft 1986-1989, 1990
II. Syntax
The syntax to implementing CLOCK is very simple:
CALL CLOCK(row, col, attr, Func)
row - The CRT line to display the time display at.
col - The CRT column to display it at.
attr - The color in attribute form to use in the display.
Func - CLOCK function to perform:
0 = uninstall clock
1 = normal installation
2 = quiet installation (do not beep at half hour
intervals.)
Since CLOCK uses TSR type programming techniques, it must be
uninstalled when you are done with it. This cannot be understated:
CLOCK MUST BE UNINSTALLED BEFORE PROGRAM TERMINATION.
This includes program crashes! In the event of a runtime error
or crash, CLOCK must be uninstalled before your application exits to
DOS. This means if you use ON ERROR type error traps, a call to
uninstall CLOCK should be performed. Since CLOCK takes over some very
key system interrupts, it is not advised that you use it with other
TSR type programs or routines without a THOROUGH checking out of their
compatibility.
III. Programming Considerations
CLOCK cannot be accidentally twice, CLOCK checks for such an
attempt and precludes it. Should you wish to change the attributes or
location of the display, perform two calls: the first to uninstall
CLOCK then another to reinstall it with the new color or location (or
both). CLOCK does no internal display preservation, so should you do
an uninstall-install routine to change color or location, the last
image of the first clock installation will remain unless you restore
that portion of the screen or CLS or whatever.
Copyright (C) InfoSoft 1986-1989, 1990
C. QCalc
Copyright (C) InfoSoft 1987 - 1990, 1991
I. Introduction
QCalc is one of the most powerful and useful callable subroutine
in _any_ QB/BASCOM add on package. QCALC has every feature found in a
cheap calculator, plus some. QCalc handles values ranging from -2.147
to +2.147 BILLION in either decimal or fixed point (as in dollar
values).
Such a full featured routine is great in and of itself, but being
written entirely in assembler, QCalc takes _under_ 4k in your program!
QCalc is completely self sufficient: all keyboard, video, bios and
math calculations are _internal_ to it. There are no dependencies on
other library routines you may or may not have available to you!
Any sort of bookkeeping or number based QB/BASCOM application
can benefit greatly from QCalc. QCalc is _not_ a TSR but it does
remember the result from the last invocation within the same applica-
tion!
II. Calculator Operation
When first invoked, QCalc will draw a representation of a small
hand held calculator on the screen, complete with number keys and math
operators. This true to life representation makes it ideal for
accounting type systems where the user or operator is not necessarily
a computer aficionado.
QCalc invokes the Num-Lock key for even more convenience, and
as numbers are pressed, the presses are replicated on the calculator
display. Remember, all this power is available to you and your
program with ONE simple CALL invocation.
The default mode is Decimal Fixed Point entry since that is
the most likely method for adding sales, calculating tax etc.
Math Functions supported:
+ ... Addition
- ... Subtraction
* ... Multiplication
/ ... Division
= ... Equals (the Enter key also acts as an implicit equal sign).
Copyright (C) InfoSoft 1986-1989, 1990
Numeric Entry:
In Fixed Point mode, the decimal can be used to fix the point.
That is, entering 1 - 2 - 3 - 4 would result in a display of 1234.00,
however, 1 - 2 - . - 3 - 4 would result in 12.34.
Commas are not supported as entry characters in decimal mode,
however they are displayed as needed.
Other Calculator Operations:
[Alt -] \ Changes the sign of the entry (like the '+/-'
[Alt +] / key on a calculator). Note that these are
the _top row_ plus and minus keys, not the
grey ones. We would gladly use the grey one
also (or instead), but the BIOS does not read
them when used in combination with the Alt key.
As operations are performed, and results displayed, QCalc
simulates a physical calculator by retaining a display of the
last 5 entries or results, ie a tape.
[Esc], [Alt-Q] Abortive type exit - nothing returned
[Alt-R] Alt-R, for RETURN, closes the calculator window
and returns to your application, returning
the last result shown on the calculator.
[Alt-E], <E> E or Alt-E is for Clear Entry.
Clears the number being entered or already
entered.
[Alt-C], <C> C or Alt-C is Clear All
Clears the entry and history by scrolling
the tape to clear.
[Alt-D] Selects Decimal as the operating base. This
is the default when first called. Should you
switch to Fixed Point, QCALC will remember and
come up in that mode.
[Alt-F] Selects Fixed Point as the operating mode.
BackSpace The backspace key is fully supported while
entering digits. When used on a result, the
backspace key acts as the Clear Entry key.
Copyright (C) InfoSoft 1986-1989, 1990
Just as in a physical calculator, a result can be rolled over
into an entry. Example:
4 * ; an entry
4 = ; 4*4 = ??
16= ; 16 is a _result_
+ ; tapping plus turns 16 into an _entry_ !
16+
III Operation Tips
QCalc can do any addition, multiplication, division or subtrac-
tion as long as the result and both operands are within the +/- 2.147
BILLION range. Overflowing or underflowing this range will cause
numbers to wrap: ie 2.147 BILLION plus 1 = - 2.147 BILLION and
vice-versa.
Percentages, as in a tax calculation, are easily handled with
multiplication or division:
Method 1 ( 2 step process):
Tax rate of 5% on 34.65
34.65 * ; result of addition etc turned into entry
.05 ; enter as "." + "0" + "5"
= ; hit enter or equal
1.72 ; this is the 5% tax amount (a _result_ !)
+ ; turn result into entry
34.65 = ; add back in the taxable amount
36.37 ; Total amount due
Note: For various reasons, the 5% amount, which is actually
1.728 is returned as 1.72 not rounded to 1.73.
Method 2 (1 step process):
34.65 * ; result of addition etc turned into entry
1.05 ; enter as "1" - "." - "0" - "5"
= ; hit enter or equal
36.38 ; this is the 5% tax amount (a _result_ !)
Note: This is not only simpler and faster, it is more
accurate! However many, many people do not understand
that the total amount is going to be 100% of the
taxable amount _plus_ 5%, ie 105% or (n * 1.05).
Copyright (C) InfoSoft 1986-1989, 1990
To be able to isolate the tax amount, as might be needed on an
itemized bill, just roll over the result into an entry and subtract
the subtotal. Continuing from above, this is done like this:
- ; roll result into a entry
34.64 ; deduct the subtotal
1.73 = ; the amount added to subtotal ie the tax.
IV Syntax
The immense power and functionality of QCalc is invoked with a
mere 5 parameters that control virtually everything:
Syntax:
DECALRE FUNCTION QCalc&(Row%, Col%, Body%, Scrn%, Button%, Speed-
Mode%)
..
..
..
RetVal& = Calc(Row, Col, Body, Scrn, Button, SpeedMode)
C. Parameters:
RetVal& - QCalc will return to you the last _result_ value
on the QCalc display. An entry value will not
be returned. That is, entering '1+1=' will return
2. Simply entering 1 only, with no operation, will
return the result of the last operation.
This _must_ be a long integer.
Row, Col - Denotes the upper left row, col coordinates for
the calculator display. The size of the calculator
display is 31 characters wide, 20 columns tall -
roughly 1/3rd of the screen. QCalc is not only
functional but it is very smart too: should you pass
invalid coordinates for the row/col, it will adjust
them so that the calculator display does not wrap.
Three attribute values are passed to customize the calculator
display specifically to your needs. QCalc will use the correct
display mode for mono vs color/EGA/VGA displays, but does no second
guessing on the attributes you pass. Be sure that the attributes you
choose are appropriate for the display present.
EGA's must be in 25 row mode or QCalc simply exits gracefully.
Copyright (C) InfoSoft 1986-1989, 1990
Body - The color to use in the calculator body. This
is the predominant color used.
Screen - The color to use on the 5 line calculator display.
Since the end user will be focusing on this, it
should be an easy to read color, however certain
attributes can replicate a LCD appearance to
make the display even more realistic.
Button - This color is used a very little, only to simulate
button presses and the like. Since it is used on
the calculator body, some very interesting effects
can be created using totally different background
colors or the same so that just the key text changes.
SpeedMode - This allows the programmer or end user to tailor
a portion of the operation characteristics. When
a numeric key (0-9), E or C is pressed, the
appropriate display is briefly recolored with
the Button Color and a tone sounds. The SpeedMode
parameter allows you to set the duration for the tone
in clock ticks (1 / 18.2 seconds (we suggest 2).
This time is not system dependant so it makes no
difference if QCALC is called on a 386 or a 8088
machine. However, you may want to turn off the beep
tone or speed it up or slow it down - the SpeedMode
parameter affords you this option.
Additionally, after the beep, QCALC purges the
keyboard buffer of type ahead characters, which is
also disabled with the SpeedMode parameter.
SpeedModes 0 to 4 do not purge the type ahead buffer
and represent in clock ticks, how long the tone
should sound in the beep/button recolor operation.
Zero is the shortest, with the beep/recolor disabled,
four is the longest with it taking about 1/2 second
(twice as long as a BASIC or DOS Error BEEP !). For
reference, we recommend 2.
SpeedModes 5 to 9 represent the same clock tick count
as 0 to 4, that is, SpeedMode 5 disables the beep
with the difference being that SpeedMode 5 to 9 DO
purge the type ahead buffer. So SpeedMode 7 provides
the same display effect as 2 with the difference
being that 7 will eat up any keys waiting in the
keyboard buffer.
Copyright (C) InfoSoft 1986-1989, 1990
V. Programming Considerations
QCalc returns the last _result_ on the display to your program.
This means that in a book work type program, you could pop up QCalc to
allow the user to add up sales or paid outs, and when they leave QCalc
via [Alt-R], QCalc will return the last result shown on the calculator
display! Your program could then automagically insert that value on
the screen and the proper variable!
If the user leaves QCalc via [Esc] or [Alt-Q], QCalc simply 'pops
down' and does not attempt to return anything. You can force a return
to your program by simply setting up a loop until QCalc DOES return a
value. This maybe helpful in cases where the calculator covers up
some of the entry items on the screen forcing the user to occasionally
'pop down' to read more info. Ex:
DO UNTIL RetVal& <> 0
RetVal& = QCalc(row, col, attrs, attrb, attrf, speed)
IF RetVal& = 0 ' no return
LOCATE 23, 10
PRINT "Return Required - Press any key for calculator."
ELSE
EXIT DO ' return was okay get outta LOOP
END IF
x$=INPUT$(1) ' get a key, any key
LOCATE 23,10 ' cover over msg
PRINT SPACE$(46)
LOOP
NOTE! NOTE! NOTE!
QCalc returns a _LONG_ integer. These are 32 bits and require
that your receiving variable must be an _LONG_integer. Attempting to
assign the result to an integer _will_ result in OVERFLOW.
The return is in decimal mode. If your application is using
fixed point numerics, simply divide the return by 100.
Notes
Within the same program (ie without CHAINing, RUNning or spawning
a new module), QCalc retains the display of the last entry or result.
Theoretically, this allows the user to pop up QCalc, add up some
numbers, pop down to get more info from the screen and return to
right where they were - previously entered data is _not_ lost!
It is also important to note that second and third and fourth
calls to QCalc do _not_ have to be at the same location for QCalc to
pop up the same display!
Copyright (C) InfoSoft 1986-1989, 1990
QCalc automagically engages the Num Lock key when invoked and
retores it when exiting. Since we are not afflicted with one of the
'enhanced' 10x key keyboards, we are not yet sure what this does with
them. However, it is in deference to them and the nonspatial -kine-
sthetic layout that no function keys are used.
We hope you enjoy QCalc and find it's vast power and incredible
ease of use to be of benefit in your program. QCalc is completely
ported to 'C' language so that should you learn 'C' or are already
somewhat multi lingual, this invaluable tool can 'go with you' and
your programming endeavors.
Copyright (C) InfoSoft 1986-1989, 1990
D. FlexMenu
Copyright InfoSoft 1988 - 1990, 1991
Flexmenu is a snappy, full featured, multi purpose menu-select
subprogram that supports a plethora of features with a minimum of
setup or parameters to manage.
Many of the programs we write require easy to use and intuitive
menus for novices, yet navigation still needs to be flexible enough so
as not to frustrate experts. We routinely use FlexMenu in these
situations because it fits all these needs and more.
Syntax:
item = MenuChoice% (Menu$(), Trow%, LCol%, Nattr%, Hattr%,_
title$, Mark%(), XtdChc%)
Using the list of items in Menu$(), Flexmenu displays a box on
the screen at the location specified by TRow, LCol. FlexMenu auto-
matically calculates the rest of the coordinates (length and width).
If the number of choices is greater than 14, the box is truncated to
hold the first 14, with the rest being displayed thru the use of the
arrow keys. When this is the case, and selections are off the screen
either above or below, up and/or down arrows (ASCII 24 and 25) will be
located on the right border. Additionally, FlexMenu displays a
relative scroll bar along the side of the menu, showing where in the
list the highlighted selection resides.
The list of choices or menu items is in the color attribute
specified by Nattr (Normal ATTRibute), and the current selection is
highlighted in color HAttr. An optional title is centered across the
top of the box.
FlexMenu will elegantly handle as many choices as you can fit into
string space. Theoretically, this is 65535, but unless your program
has no code, there is little chance this much can be allocated. As we
mentioned, for appearances, the box is never larger than 14 selec-
tions. Navigation is intuitively managed with the arrow keys (Up and
Down), Pg Up, Pg Dn, Home and End - all doing what you would expect.
Additionally, FlexMenu responds to a alpha search - press "A" will
locate and go to (but not select) the first item after our current
item starting with "A" or "a". Pressing [Enter] returns to your code
the index number of the item pressed. If we are on item 1527, 'item'
will be set to 1527.
If you prefer your FlexMenu with a background 3-D shadow, and most
of us do, simply place a call to BShadow ( "CALL BShadow(1)" ) before-
hand - this makes all Boxes calls automatically shadowed.
We would find FlexMenu highly useful if that was all it did but it
does much, MUCH more:
Copyright (C) InfoSoft 1986-1989, 1990
1) Flexmenu will automatically center the display (which we use
almost exclusively) by setting both TRow and LCol to -1. This pre-
vents you from having to twiddle and map out where the center is.
2) If you are performing list processing, FlexMenu will allow you
to 'feed' a variable representing the last item selected. That is, if
on the last call to FlexMenu, the user selected item 127, we can
initialize the next call to FlexMenu to allow that the last item
selected is highlighted on the screen! Since this is a modification
from the initial releases of FlexMenu, and is more or less an ancil-
lary function, this variable is passed and defined in a COMMON SHARED
block. If you have no need for this feature, simply do not define the
common block.
To use this feature, define a common block as follows:
COMMON SHARED /FlexVars/ FlexFeed%, FlexAll$
When FlexFeed is initialized to a value within the range of the
menu passed, FlexMenu will be scrolled so that menu selection cor-
responding to it is on the display.
The second COMMON variable controls a Mark All function covered
later.
3) It responds to extended keystrokes. If we highlight item 156,
and press enter, item is set to 156. If we press [Alt-Q] instead,
item is still set to 156, but the extended choice parameter (XtdChc)
is set to 16 (the ASCII code for Alt-Q). This allows us to manage
multiple functions from one menu. For example, we might use DIRA to
load a string array and FlexMenu to display the file names and from
that, [Alt-D] might delete the chosen file, but [Alt-L] might list it.
Then via a SELECT CASE statement the desired functions can be swiftly
carried out.
To filter out unwanted extended choices, simply place the call to
FlexMenu in a DO or WHILE loop as shown in the following example.
Copyright (C) InfoSoft 1986-1989, 1990
done = 0
DO
item = MenuChoice(menu$(), -1, -1, 78, 3, "Demo", Mark(), XtdChc)
SELECT CASE XtdChc
CASE 1, 2, 3, 4
GOSUB MoreChoices
CASE 12, 14, 15
GOSUB SomeStuff
CASE 16
GOSUB KillFile
CASE 23
' get another selection
CLS
item = MenuChoice(f$(), -1, -1, 78, 3, "Demo", Mark(), XC)
IF (XC <> 27) AND (Item > 0 ) THEN
GOSUB GoodStuff
END IF
CLS ' clear for next loop
CASE 27 ' Escape
done = 1
SYSTEM
CASE 18 ' Alt - Q
done = 1
CASE ELSE
'unsupported functions
END SELECT
LOOP UNTIL done
In this type of construction, we limit the methods of ending the
program to the 2 we are prepared to handle. In this way, the display
(Menu$()) can represent either a list of things to act upon such as
file names or a list of actions or a menu itself! Creativity in
nesting allows virtually unlimited possibilities -- we have one
program that manages some 40,000 items and menu functions in 5 Flex-
Menu calls. The novice user is always interacting with FlexMenu,
never DOS or the engine of the program.
There is even MORE!
Copyright (C) InfoSoft 1986-1989, 1990
4) FlexMenu optionally supports a "Mark Mode" or multiple select
function. By setting XtdChc to non zero upon entry, you enable mark
mode where pressing the TAB, or SPACEBAR toggles a mark for that item.
The number of marks allowed is set by XtdChc, setting it to 10 allows
10 - and only 10 - items to be marked; set to 5, only 5 would be
allowed and so forth. Marked items are tagged with bracketing " " and
" " (ASCII 174 and 175) characters (only on the display! FlexMenu
will not alter your menu array!), and all the other features remain in
effect - alpha search, navigation and extended keyboard selection.
To accomplish this, you must pass an integer array that is of the
same size as your main selection string array. FlexMenu will use this
as a set of pointers indicating which items are Marked: if elements 5,
6, 10 and 37 are set (non zero) upon exiting, then the user selected
or marked selections 5, 6, 10 and 37 from the menu. 'Item' will STILL
return as the highlighted or current item when ENTER or an extended
key is pressed - it is up to you to use it or not. If the Mark
integer array is not the same size as the string array of choices,
Mark Mode is disabled. However, if mark mode is NOT desired, enter
FlexMenu with XtdChc set to 0 and/or dimension Mark() to a single
element.
You will recall that the COMMON block contains a vaiable names
"FlexAll$". If defined, when the user presses the key defined by you
as FlexAll$, ALL the items in the list are MARKED. This feature
respects the value of the maximum MARKS allowed by XtdChc, so this
feature is only available when all XtdChc=UBOUND(Menu$), ie all items
in the list can be marked. For example to define Alt-Q as the Mark
All key,
FlexAll$ = CHR$(0) + CHR$(16) ' Extended key code for Alt-Q
If/when the user preses Alt-Q all menu items will be marked.
5) FlexMenu will also "remember" previous marks upon subsequent
calls unless you REDIM the MARK array. FlexMenu examines Mark() as it
is setting up and treats non zero elements as marks. That is, upon
initializing it does not assume that it is the first time. Using
this, you can "suggest" selections by setting the corresponding Mark()
element before calling FlexMenu - the user can of course toggle it
off, but in cyclical applications, the user need not remark previous
selections.
We use FlexMenu almost exclusively in our menu driven applica-
tions, since it is powerful, fast, relatively small and has many
features and have found it to meet most every need.
NOTE: FlexMenu requires the QPrint, Scroll, QPrintV, Painter,
StrLen and Boxes object modules.
Copyright (C) InfoSoft 1986-1989, 1990
E. StatLine
Copyright (C) InfoSoft 1988 - 1990, 1991
I. Overview
StatLin is the name of the object file containing several rou-
tines or primitives that aid you in displaying and/or controlling a
one or two row status line. Collectively, we will refer to them as
StatLine.
These routines are:
CLX - Clear the screen except for the status line area.
SetBline - Set the bottom line of the non status line area of
the screen. Similar in function to the BASIC WINDOW
statment.
PrintStatL - Prints all or part of an array designated for the
status line.
II. Operation
The default bottom line of a screen using StatLine procedures is
row 23, or a 2 row status line as used in the demo. You can set this
to more or less depending on your needs, thus allowing you to use even
5 lines for the status area or even simulating a split screen effect.
If you use more than 1 or 2 rows for the status line however, you
will need to maintain those above 24 as PrintStatL will only print to
line 24 and/or 25). Beyond that limitation, these routines allow for
printing and updating a status line, and clearing the non status line
portion of the screen.
Copyright (C) InfoSoft 1986-1989, 1990
III. Functions
Name: SetBVLine Type: SUB Level: ASM
Syntax: CALL SetBVLine(x)
As mentioned, the default bottom line of a screen using StatLine
procedures is row 23, or a 2 row status line as used in the demo. If
you wish to reserve more or less area than that, SetBVLine will allow
you to Set the Bottom Video Line to be respected by PrintStatL and
CLX.
Note that if you set it to 23, a call to CLX will ONLY clear
lines 1 to 23, saving the bottom two status lines and preventing you
from having to redraw them. However, CLS will still clear the entire
screen.
Name: CLX Type: SUB Level: ASM
Syntax: CALL CLX
This may also be called or invoked as ClrScrn
This simply clears the non status line portion of the screen.
Where CLS would clear all 25 rows of video, CLX respects the default
bottom video line of 22 or whatever you have set it to using Set-
BVLine.
Like BASIC's native CLS statement, this also relocates the cursor
location to 1,1 by performing a call to the actual BASIC RTL (Run Time
Library) so that not only the cursor is physically relocated, but the
internal cursor location variables held by the QB RTL are reset
allowing CSRLIN and POS(0) as well as PRINT to act as expected. That
is, an explicit LOCATE 1,1 is not needed to complete the CLX/ClrScrn
function.
Name: PrintStatL Type: SUB Level: ASM
Syntax: CALL PrintStatL(StatMsg(1), Action, Attr)
This prints all or part of a 2 element fixed length 80 character
string array to the status line area of the screen in the designted
color.
Copyright (C) InfoSoft 1986-1989, 1990
1. To pass a fixed length string array to a CALLed ASM sub, you
must hide it in a TYPE structure by setting up a user defined
TYPE that is simply a single 80 character string.
Ex:
TYPE struct ' tell QB what it looks like
fls AS STRING * 80
END TYPE
DIM StatMsg(2) AS struct ' order one
2. Also to pass a TYPE structure to an ASM routine, you must
DECLARE it using the keyword ANY. So the DECALRE for
PrintStatL would be:
DECALRE SUB PrtSL(MsgArry AS ANY, Action%, Attr%)
3. At this point, we may fill the array with messages. Feel free
to use LSET or RSET with the array to justify strings. Example:
StatMsg(1).fls = " Time: " + TIME$ + " Temp: "+ degree$ + msg$
StatMsg(2).fls = " Code: " + Information$
4. Finally invoke it with the desired action code and attribute:
CALL PrtSL(StatMsg(1), 0, Attr)
ActionCode tells PrtSl what action to perform:
0 = Print/Update both lines 24 and 25
1 = Print/update line 24 only
2 = Print/update line 25 only
In more sophisticated applications, you can define more than 2
elements for the message array and selectively update higher offsets
in the array. For instance, if your program has 5 main function
levels, you might need 5 different status line displays. Using a 2
line display means we need 10 elements so,
DIM StatMsg(10) AS struct ' set up 5 status line SETS
When we are working on the Main or top level we invoke elements
1 and 2 to print to lines 24 and 25 as normal (above). For subsequent
levels we pass the element to be mapped or printed to line 24, the
second activity level would be:
Copyright (C) InfoSoft 1986-1989, 1990
CALL PrtSL(StatMsg(3), 0, Attr)
' element 3 goes to 24, 4 to line 25
' level 3:
CALL PrtSL(StatMsg(5), 0, Attr)
' and so on to level 5:
CALL PrtSL(StatMsg(9), 0, Attr)
Of course, your use of OPTION BASE 0 means you subtract one from
the element passed.
Notes:
Being a fixed length string, a very large number of status line
messages can be stored in your fixed length sting array, but be sure
to use the /ah switch if the array is to be more than 64k. Also,
large fixed length string arrays should ALWAYS be even multiples of 2.
This is so that if and when they span a segment boundary, the segment
boundary will break at the start of an element and NOT in the middle
of a string or structure.
QB inititializes a fixed length string to NULLs, NOT SPACES, so
displaying a message array that you have not modified, may result in
unexpected results.
PrintStatL expects a 2 line status area, so to use only line 25,
your message array would still have to be 2 elements per "level", but
every other one would be blank or NULL. MsgArry(1) always maps to
line 24, as does 3, 5, 7, 9 etc. These would be blank, but 2, 4, 6, 8
etc would be filled for mapping to line 25 when you want to use only
line 25. Note that SetBVLine has no effect on PrintStatL only on CLX.
PrintStatL expects the message array to be a 80 character string
array - if you dimension it to a smaller number the memory contents
immediately following the arry will be printed. Ex: if you DIM it to
STRING * 60 (rather than 80), line 24 would display the first element
PLUS the first 20 characters of the second, and the bottom line would
display the next 40 characters of the second element PLUS what ever
garbage is in the next 40 bytes of memory.
Copyright (C) InfoSoft 1986-1989, 1990
F. DialogBox
Copyright (C) InfoSoft 1989 - 1990, 1991
I. Overview
If you've ever carefully looked at the code for most finished
programs of any size, you can often be amazed at the amount of code
that is dedicated simply to validating user I/O. Be it precluding
invalid filenames, verfying an input character or reacting to an error
situation, vast portions of code (and naturally, coding time) in
'bullet proof' programs end up dedicated to this.
Naturally if you use one menuing method and one or two user I/O
routines and CALL or GOSUB to them, your program size could be con-
siderably reduced. That is what we did on one application: all
select-from-menu inputs were replaced by FlexMenu(qv), all extended
string input was replaced by MFed, and all program-to-user messages
(like "Overwrite File?" "File Does not exist!" etc) with the likes
of PGetCh, GetCh and WINDOWS were replaced by Boxes. With little
other code structure changes, the program shrunk 17% !
DialogBox is an SAA style input box designed loosely after the
ubiquitous dialog boxes found in QB, QBX, TC and QC as well as other
integerated applications (MICROSOFT WINDOWS...). DialogBox allows you
a simple, compact, fast, all-pupose method of communicating error
conditions and/or choices to the end user, and get a delimited re-
sponse from them.
The functionality of DialogBox comes from a minimum of parameters
needing to be passed. You pass only a few strings, and the routine
automatically determines the size of the box.
Copyright (C) InfoSoft 1986-1989, 1990
II Parameters
Name: DialogBox Type: FUNCTION
Syntax: ret$ = DialogBox$(msg$, prompt$, okay$)
Msg$ - Typically, this would be used to explain or describe a
problem or error, or to pose the premise of a question
you wish to ask. Example:
"File Not Found"
"Error writing to disk"
"Printer not online"
"Delete all files"
Prompt$ - This might typically explain the list of possible
actions or choices or expand on the Msg$ displayed.
Examples:
"Abort or Retry?"
"Swap Disks, Retry"
"Fail or Retry"
"Yes, No or Cancel"
Okay$ - Tells DialogBox what input is ok. This list is
displayed in the DialogBox on the line below prompt$.
Additionally, if Okay$ is NULL ( "" ), then DialogBox
will accept any key press as an act of acknowledgment by
the user and "< OK >" is displayed where the OK list
normally would be. This list must be in upper case see
GetCh.
ret$ - Returns to your calling program the upper case character
pressed from the okay list that allowed the user to exit
DialogBox.
Copyright (C) InfoSoft 1986-1989, 1990
Syntax example:
msg$ = "Delete marked Files?"
prompt$ = "Yes, No or Cancel"
okay$ = "YNC"
ret$ = " "
OutPut: (this may be distorted depending on your printer)
Delete Marked Files?
Yes, No or Cancel
<Y> <N> <C>
The entire box is cenetered horizontally and vertically on the
display, all text is centered within the box, a single line frame
border is used and the color attribute is black on white reverse
video. As mentioned, the left and right borders of the box are
calculated internally to DialogBox so you need not mess with loca-
tions.
DialogBox does NOT do any screen saving and it does not check for
string length errors: a msg$ length of more than 78 characters will
surely cause unexpected and/or unknown results.
The defaults used in DialogBox (location, color etc) are designed
to be as SAA-like as possible, to make invoking it as easy as possible
and as always, lightening fast. However, the defaults can be changed
either for current or subsequent calls.
In the example, you will note that DialogBox parses the passed
okay$ and displays them individually within brackets. If the list of
okay responses is more than 5 however, or both the message and prompt
are abnormally short, it will simply list them: QWERTY is simply
centered.
Copyright (C) InfoSoft 1986-1989, 1990
III Altering DialogBox defaults
As is, the DialogBox defaults eliminate many decisions such as
colors to use depending on the monitor type, where to locate it and so
forth, and provide a SAA appearance to the program. However some
people are going to just die if they can't use colors with it or
locate it somewhere else (in fact, re-locating the box may be required
in some cases where something relevant to the message gets covered up
by it).
So, should you want to change any of these, we have devised a sub
program to set user defined defaults:
Name: DBoxSetUDef Type: SUB
CALL DBoxSetUDef(TRow, LCol, Frame, BAttr)
TRow - The top row for DialogBox
LCol - The left column for the location
Frame - The style of frame to be used (see BOXES for a complete
list)
BAttr - The new default color to use
Once called, DBoxSetUDef sets a flag to instruct DialogBox that
user defined parameters are in effect and to use them. These para-
meters, in fact become the new defaults until you reset them or clear
them. This allows you to position and color the box any way you like.
Note that you only need to set the Top Row and Left Column: DialogBox
will still calculate the bottom and right box frames based on the
length of the strings. You cannot make the box bigger and locations
are NOT verified: Setting the top row to 52 will have unwanted re-
sults. Note that using DBoxSetUDef means that ALL the parameters are
changed.
Name: DBoxClrUDef Type: SUB
CALL DBoxClrUDef
This merely clears any user defined parameters from DialogBox and
allows it to once again execute with default parameters.
Copyright (C) InfoSoft 1986-1989, 1990
Name: DBoxSound Type: SUB
CALL DBoxSound(SFlag, Frequency, Duration)
Since I often find myself sounding the speaker just as I pop up a
DialogBox, we have gone ahead and built in sound capability. The
default tone for this is the equivalent of using GLib's SpeakerSound
routine: CALL SpkrSnd(1200, 1)
The default for the sound is ON with a frequency of 1200 and a
duration of 1. To alter any of these, simply use DBoxSound. Setting
SFlag to 0 turns the sound off, 1 turns it on. To alter the default
tone, call DBoxSound with SFlag set to one and frequency and duration
set to the desired values.
IV Usage
One way we have used this was to have all possible program
messages, prompts etc stored in an Fixed length string array and when
needed, we simply called a DBox handler with an ActionCode. This
handler then copied the strings to a normal array, saved the screen
image, called DialogBox, erased the temp array, restored the screen
and returned the selected character to the main program.
Alternatively, a larger program that could not spare the memory,
left all such messages in a random file. The box handler then fetched
the necessary text from the file (keyed on the ActionCode) into simple
strings, called DialogBox and then returned the input. Using such
techinques, the main program need only determine error conditions, and
act on reponses - all the I/O with the user is relagated to a sub-
program.
There is a little less flash and dazzle to DialogBox than emulat-
ing the same with MFed and WINDOWS but in very large applications,
where code space or development time is critical, rather than spending
time with setting up actions and such DialogBox can provide a uniform,
straight forward very fast approach to simple prompted user I/O.
Copyright (C) InfoSoft 1986-1989, 1990